/////////////////////////////////////////////////////////////////////////////////
// odoDB.c  C Test file for neptuner                                        //
// Copyright 2009, Ocodoco Unlimited                                           //
/////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////
/**
	* \file    odoDB.c
	* \author  Sonofdelphi
	* \brief   odo test DB Implementation.
	*/
/////////////////////////////////////////////////////////////////////////////////

#include "odoDB.h"
#include "odoDBQ.h"

//////////////////////////
/* **********************/
/* DBCOL PROPERTIES  */
/* **********************/
//////////////////////////

unsigned char gnAtomRecordID;
unsigned char gnBConfupRecordID;
unsigned char gnRollBConf;

bool gbXSessionEnabled;
bool gbXSessionLocked;
bool gbXSessionRetry;
bool gbXSessionMaster;

//////////////////////////
/* **********************/
/* DBCOL MEMBERS     */
/* **********************/
//////////////////////////

DBRecord gxRecordTemp;
DBRecord gxRecordFlow;
DBRecord gxAtomRecord;
DBRecord gxRecordBConfupd;

void 
odoDBDelegateBConfupRecord
(
	void
)
{
	int nQueryStat;

	nQueryStat = UNDEF;

	nQueryStat = DBSendFlowRecord(eForce);
	ASSERT_SUCCESS(nQueryStat);

	gnBConfupRecordID = Increment(gnBConfupRecordID,
		(DB_MAX_Record_ID+1));

	nQueryStat = DBMacroQCommit(&gxRecordBConfupd);
	ASSERT_SUCCESS(nQueryStat);

	return;
}/* End of odoDBDelegateBConfupRecord */ 

void 
odoDBDelegateValidConf
(
	void
)
{
	int nQueryStat;
	bool bIsQEmpty;

	nQueryStat = UNDEF;
	bIsQEmpty = TRUE;

	nQueryStat = odoDBRetryConfirmRetry();
	ASSERT_SUCCESS(nQueryStat);

	nQueryStat = odoDBTimeoutCommit(FALSE);
	ASSERT_SUCCESS(nQueryStat);

	gnAtomRecordID = Increment(gnAtomRecordID,
		(DB_MAX_Record_ID + 1));

	nQueryStat = DBAtomQIsEmpty(&bIsQEmpty);
	ASSERT_SUCCESS(nQueryStat);

	if (FALSE == bIsQEmpty)
	{
		nQueryStat = odoDBMacroCommit(TRUE);
		ASSERT_SUCCESS(nQueryStat);
	}/* End of if */ 

	gbXSessionLocked = FALSE;
	gnRollBConf = 0;

	return;
}/* End of odoDBDelegateValidConf */ 

void 
odoDBDelegateInvalidRecord
(
	void
)
{

	return;
}/* End of odoDBDelegateInvalidRecord */ 

void odoDBDelegateCancel
(
	void
)
{

	return;
}/* End of odoDBDelegateCancel */ 

void 
odoDBDelegateSessionRecord
(
	void
)
{
	int nQueryStat;

	nQueryStat = UNDEF;

	if(TRUE == gbXSessionMaster)
	{
		nQueryStat = odoDBRetryConfirmRetry();
		ASSERT_SUCCESS(nQueryStat);

		gbXSessionMaster = FALSE;

		DBSendFlowRecord(eSession);
	}/* End of if */ 

	return;
}/* End of odoDBDelegateSessionRecord */ 

void 
odoDBInit
(
	void
)
{
	int nQueryStat;

	nQueryStat = UNDEF;

	nQueryStat = DBQSetup();
	ASSERT_SUCCESS(nQueryStat);

	#ifdef XSession_1
	gbXSessionMaster = TRUE;
	#else
	gbXSessionMaster = FALSE;
	#endif

	gnAtomRecordID = 0;
	gnBConfupRecordID = 0;
	gnRollBConf = 0;

	gbXSessionLocked = FALSE;
	gbXSessionRetry= FALSE;
	gbXSessionEnabled = TRUE;

	return;
}/* End of odoDBInit */ 

void 
odoDBRecordProcess
(
	void
)
{
	DBRecordType		eRecordType;
	unsigned short      u16RecordSize;
	unsigned short		u16Size;
	void			nQueryStat;
	unsigned char		nTotal;
	bool                bIsValidRecord;
	bool                bIsQEmpty;

	nQueryStat = UNDEF;
	bIsValidRecord = FALSE;
	bIsQEmpty = TRUE;

	ASSERT(gbXSessionEnabled);

	nQueryStat = DBBConfupQPop( &gxRecordBConfupd);
	ASSERT_SUCCESS(nQueryStat);

	nQueryStat = DBBConfupQIsEmpty(&bIsQEmpty);
	ASSERT_SUCCESS(nQueryStat);

	if (FALSE == bIsQEmpty)
	{
		nQueryStat = odoDBRecordCommit(TRUE);
		ASSERT_SUCCESS(nQueryStat);
	}/* End of if */ 

	nQueryStat = DBRecordBufferSize(&gxRecordBConfupd,
		&u16Size /* Check */
	);
	ASSERT_SUCCESS(nQueryStat);

	nQueryStat = DBRecordIsValid( (unsigned char*)&gxRecordBConfupd,
		u16Size, /* Check */
		&bIsValidRecord );
	ASSERT_SUCCESS(nQueryStat);

	if ( FALSE == bIsValidRecord )
	{
		nQueryStat = odoDBDelegateInvalidRecord();
		ASSERT_SUCCESS(nQueryStat);
		return;
	}/* End of if */ 

	nQueryStat = DBRecordBufferSize(&gxRecordBConfupd, &u16RecordSize);
	ASSERT_SUCCESS(nQueryStat);

	nQueryStat = DBRecordBufferStructize(&gxRecordBConfupd, u16RecordSize);
	ASSERT_SUCCESS(nQueryStat);

	nQueryStat = DBRecordFlowCharType(gxRecordBConfupd.nRecordFlow,
		&eRecordType);
	ASSERT_SUCCESS(nQueryStat);

	if(TRUE == gbXSessionMaster)
	{
		if(eSession !=eRecordType)
		{
			return UNDEF;
		}/* End of if */ 
	}/* End of if */ 

	if ( eMacro != eRecordType)
	{
		nQueryStat = DBFlowRecordSave(
			gxRecordBConfupd.nRecordFlow);
		ASSERT_SUCCESS(nQueryStat);
		return;
	}/* End of if */ 

	nQueryStat = DBRecordFlowCharTotal(gxRecordBConfupd.nRecordFlow,
		&nTotal);
	ASSERT_SUCCESS(nQueryStat);

	if (nTotal == Predecessor(gnBConfupRecordID,
			(DB_MAX_Record_ID + 1)))
	{
		nQueryStat =DBSendFlowRecord(eForcePrev);
		ASSERT_SUCCESS(nQueryStat);

		return;
	}/* End of if */ 

	if ( gnBConfupRecordID != nTotal )
	/* Is an UnBConfup Record */
	{
		nQueryStat = odoDBDelegateUnBConfupRecord();
		ASSERT_SUCCESS(nQueryStat);

		return;
	}/* End of if */ 

	if ( gnBConfupRecordID == nTotal)
	{
		nQueryStat = odoDBDelegateBConfupRecord();
		ASSERT_SUCCESS(nQueryStat);
		return;
	}/* End of if */ 

	return UNDEF;
}/* End of odoDBRecordProcess */ 

void 
odoDBMacroSendRecord
(
	void
)
{
	unsigned short u16RecordSize;
	int nQueryStat;

	nQueryStat = UNDEF;

	ASSERT(gbXSessionEnabled);

	if (FALSE == gbXSessionRetry)
	{
		if (FALSE == gbXSessionLocked)
		{
			nQueryStat = DBAtomQPop(&gxAtomRecord);
			ASSERT_SUCCESS(nQueryStat);

			nQueryStat = DBRecordFlowChar(
				eMacro, gnAtomRecordID,
				IMMEDIATE, 
				&gxAtomRecord.nRecordFlow
			);
			ASSERT_SUCCESS(nQueryStat);

			gxAtomRecord.nVeriSign=gxAtomRecord.nVeriSign ^
			gxAtomRecord.nRecordFlow;

			nQueryStat = DBRecordBufferize(&gxAtomRecord);
			ASSERT_SUCCESS(nQueryStat);
		}/* End of if */ 
		else
		{
			return;
		}/* End of else */ 
	}/* End of if */ 

	nQueryStat = DBRecordBufferSize(&gxAtomRecord,
		&u16RecordSize);
	ASSERT_SUCCESS(nQueryStat);
	nQueryStat = DBSendRecord((unsigned char*)&gxAtomRecord,
		u16RecordSize);

	if ( UNDEF == nQueryStat)
	{
		gbXSessionRetry = TRUE;
		odoDBMacroCommit(TRUE);
		return UNDEF;
	}/* End of if */ 

	gbXSessionRetry = FALSE; 

	nQueryStat = odoDBRetryConfirmStart();
	ASSERT_SUCCESS(nQueryStat);

	gbXSessionLocked = TRUE; 
	gnRollBConf=0; 

	return;
}/* End of odoDBMacroSendRecord */ 

void 
odoDBMacroRecordRetry
(
	void
)
{
	unsigned short u16RecordSize;
	int nQueryStat;

	nQueryStat = UNDEF;

	ASSERT(gbXSessionEnabled);

	if(TRUE == gbXSessionMaster)
	{
		nQueryStat = DBSendFlowRecord(eSession);
		ASSERT_SUCCESS(nQueryStat);

		nQueryStat = odoDBRetryConfirmStart();
		ASSERT_SUCCESS(nQueryStat);

		return;
	}/* End of if */ 

	if(FALSE == gbXSessionLocked)
	{
		return;
	}/* End of if */ 

	if ( (gnRollBConf < DB_MAX_RollBConf))
	{
		nQueryStat = DBRecordBufferSize(&gxAtomRecord,
			&u16RecordSize);
		ASSERT_SUCCESS(nQueryStat);

		nQueryStat = DBSendRecord((unsigned char*)&gxAtomRecord,
			u16RecordSize);
		ASSERT_SUCCESS(nQueryStat);

		++gnRollBConf;

		nQueryStat = odoDBRetryConfirmStart();
		ASSERT_SUCCESS(nQueryStat);

	}/* End of if */ 
	else
	{
		gnRollBConf = 0;
		gbXSessionEnabled = FALSE;
	}/* End of else */ 

	return;
}/* End of odoDBMacroRecordRetry */ 

void 
odoDBMacroRecordCommit
(
	unsigned char   *pnMacro,
	unsigned short  u16Size
)
{
	int nQueryStat;

	nQueryStat = UNDEF;

	ASSERT(gbXSessionEnabled);
	ASSERT(pnMacro);
	odoDB_FAIL_ON_SIZE_EXCEEDS(u16Size, DB_MAXLEN);

	gxRecordTemp.SOP[0]=64;
	gxRecordTemp.SOP[1]=64;
	gxRecordTemp.nMacroSize=(unsigned char)u16Size;

	nQueryStat = DBRecordFlowChar(eMacro,
		0,
		IMMEDIATE,
		&gxRecordTemp.nRecordFlow);
	ASSERT_SUCCESS(nQueryStat);

	nQueryStat= odoMemcpy8(gxRecordTemp.anMacro, pnMacro, u16Size);
	ASSERT_SUCCESS(nQueryStat);

	DBRecordVeriSignCompute(pnMacro,
		u16Size,
		&gxRecordTemp.nVeriSign);

	gxRecordTemp.nVeriSign = gxRecordTemp.nVeriSign ^
	gxRecordTemp.nMacroSize;

	gxRecordTemp.nVeriSign = gxRecordTemp.nVeriSign ^
	gxRecordTemp.nRecordFlow;

	nQueryStat = DBAtomQCommit(&gxRecordTemp);
	ASSERT_SUCCESS(nQueryStat);

	return;
}/* End of odoDBMacroRecordCommit */ 

void 
DBSendFlowRecord
(
	DBRecordType eRequestedType
)
{
	int nQueryStat;

	nQueryStat = UNDEF;

	gxRecordFlow.SOP[0] = 64;
	gxRecordFlow.SOP[1] = 64;
	gxRecordFlow.nMacroSize = 0;

	switch(eRequestedType)
	{
		case eForce:
		DBRecordFlowChar(eForce,
			IMMEDIATE,
			gnBConfupRecordID,
			&gxRecordFlow.nRecordFlow);
		break;

		case eForcePrev:
		DBRecordFlowChar(eForce,
			IMMEDIATE,
			Predecessor(gnBConfupRecordID,
				(DB_MAX_Record_ID + 1)),
			&gxRecordFlow.nRecordFlow);
		break;

		case eSession:
		DBRecordFlowChar(eSession,
			IMMEDIATE,
			IMMEDIATE,
			&gxRecordFlow.nRecordFlow);
		break;

		default:
		return UNDEF;
	}/* End of switch */ 

	gxRecordFlow.nVeriSign = gxRecordFlow.nMacroSize ^
	gxRecordFlow.nRecordFlow;

	nQueryStat = DBSendRecord((unsigned char*)&gxRecordFlow,
		DBRecord_SIZE);
	ASSERT_SUCCESS(nQueryStat);

	return;
}/* End of DBSendFlowRecord */ 

void 
DBReinit
(
	void
)
{
	gnBConfupRecordID=0;
	gnAtomRecordID=0;
	gnRollBConf=0;

	return;
}/* End of DBReinit */ 

void 
DBFlowRecordSave
(
	unsigned char nRecordFlow
)
{
	DBRecordType  eRecordType;
	void       nQueryStat;
	unsigned char     nRecordID;

	eRecordType = eUnknown;
	nQueryStat = UNDEF;
	nRecordID = 0;

	nQueryStat = DBRecordFlowCharType(nRecordFlow,
		&eRecordType);
	ASSERT_SUCCESS(nQueryStat);

	if (eForce == eRecordType)
	{
		if (FALSE == gbXSessionLocked)
		{
			return;
		}/* End of if */ 

		nQueryStat = DBRecordFlowCharMST(nRecordFlow, &nRecordID);
		ASSERT_SUCCESS(nQueryStat);

		if (nRecordID == gnAtomRecordID)
		{
			odoDBDelegateValidConf();
		}/* End of if */ 
		else
		{
			return;
		}/* End of else */ 
	}/* End of if */ 
	else if(eSession == eRecordType)
	{
		odoDBDelegateSessionRecord();
	}/* End of if */ 
	else
	{
		return UNDEF;
	}/* End of else */ 

	return;
}/* End of DBFlowRecordSave */ 


/**
	* BASELINE HISTORY
	*
	* \version 000,20090706,sod  initial version.
	* \version 001,20090901,sod  Restructured
	*/




